package com.adcc.swingui.util;

import java.lang.reflect.Method;
import java.util.Hashtable;

import org.apache.log4j.Logger;


public class ThreadInvokeMethodUtil 
{
	/**线程保存*/
	private static Hashtable< String , InvokeThread > threadPool = new Hashtable< String , InvokeThread>() ;
	/**日志*/
	private static Logger log = Logger.getLogger( ThreadInvokeMethodUtil.class ) ;
	
	private static class InvokeThread extends Thread
	{
		private  Object sourceObj ;
		private Method method ;
		private Object[] objParams ;
		private boolean isStop = false ;
		
		public InvokeThread( Object sourceObj , Method method , Object... objparams )
		{
			this.sourceObj = sourceObj ;
			this.method = method ;
			this.objParams = objparams ;
			this.setName( method.getName() ) ;
		}
		
		public boolean isStop()
		{
			return this.isStop ;
		}
		
		public void closeThread()
		{
			this.interrupt() ;
			this.isStop = true ;
		}
		
		public void run()
		{
			while( ! isStop )
			{
				if( threadPool.containsKey( method.getName() ) ) {
					try {
						stopMethodInvoke( sourceObj, method.getName() , objParams);
					} catch (Exception e) {
						log.error("线程停止失败:" + e.getMessage());
					}
				}
				threadPool.put( method.getName()  , this ) ;
				log.debug( "[U]向方法线程池中加入方法调用  方法名：" + method.getName() ) ;
				try 
				{
					method.invoke( sourceObj , objParams ) ;
					log.debug( "[U]方法：" + method.getName() + "调用完成") ;
				}
				catch( Exception ex )
				{
					ex.printStackTrace() ;
				}
				finally
				{
					isStop = true ;
				}
				threadPool.remove(method.getName());
			}
		}
	}
	
	private static Method searchMethod( Object sourceObj , String methodName , Object... objparams ) throws Exception
	{
		Method reMethod = null ;
		
		if( sourceObj != null )
		{
			Method[] methods = sourceObj.getClass().getMethods() ;
			
			if( methods != null && methods.length != 0 )
			{
				boolean findFlag = false ;
				
				for( Method method : methods )
				{
					int paramLength = 0 ;
					
					if( objparams != null )
					{
						paramLength = objparams.length ;
					}
					
					if( methodName.equals( method.getName() ) && method.getParameterAnnotations().length  == paramLength)
					{
						reMethod = method ;
						findFlag = true ;
						break ;
					}
				}
				
				if( !findFlag )
				{
					throw new Exception( "[U]没有找到调用对象中的 " + sourceObj.getClass() + " 方法" +  methodName ) ;
				}
			}
		}
		else
		{
			throw new Exception( "[U]反射调用方法出错,源对象不可为空." ) ;
		}
		
		return reMethod ;
	}
	
	public static void stopMethodInvoke( Object sourceObj , String methodName , Object... objparams ) {
		try {
			if( threadPool.containsKey( methodName ) ) 
			{
				InvokeThread currThread = threadPool.get( methodName ) ;
				threadPool.remove(methodName);
				if( currThread != null && ! currThread.isStop() )
				{
					log.debug( "[U]方法：" + methodName + "停止调用") ;
					currThread.closeThread() ;
					currThread = null ;
				}
			}
		} catch (Exception ex) {
			log.error("线程停止失败" + ex.getMessage());
		}
	}
	
	public static void invokeThreadMethod( Object sourceObj , String methodName , Object... objparams ) {
		try {
			Method method = searchMethod( sourceObj , methodName , objparams ) ;
			InvokeThread thread = new InvokeThread( sourceObj , method , objparams ) ;
			thread.start() ;
		} catch (Exception ex) {
			log.error("线程执行失败" + ex.getMessage());
		}
	}
	
	public static void main( String[] args ) throws Exception
	{
		Person p = new Person() ;
		ThreadInvokeMethodUtil.invokeThreadMethod( p , "gan") ;
		ThreadInvokeMethodUtil.invokeThreadMethod( p  , "gan", " you") ;
		ThreadInvokeMethodUtil.invokeThreadMethod( p , "ri") ;
		
		try {
			Thread.sleep( 5000)  ;
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		ThreadInvokeMethodUtil.stopMethodInvoke( p , "ri") ;
		
		p.ganni() ;
	}
}

class Person
{
	public void gan()
	{
		System.out.println( Thread.currentThread().getName() + "wori") ;
	}
	
	public void ri()
	{
		try {
			Thread.sleep( 10000)  ;
			System.out.println( Thread.currentThread().getName() + "hehe") ;
		} catch (InterruptedException e) {
		}
		
	}
	
	public void gan( String str )
	{
		System.out.println( Thread.currentThread().getName() + "wori:" + str ) ;
	}
	
	public void ganni()
	{
		try {
			ThreadInvokeMethodUtil.invokeThreadMethod(this , "gan") ;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
